home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-01 | 7.7 KB | 330 lines | [TEXT/CWIE] |
- /* Z80 Emulator: macro definitions, opcode enumerations
- Copyright (C) 1995 G.Woigk
-
- This file is part of Mac Spectacle and it is free software
- See application.c for details
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- based on fMSX; Copyright (C) Marat Fayzullin 1994,1995
- */
-
-
- // ---- bit masks for z80 flag register -------------------------------
- #define S_FLAG 0x80
- #define Z_FLAG 0x40
- #define H_FLAG 0x10
- #define P_FLAG 0x04
- #define V_FLAG 0x04
- #define N_FLAG 0x02
- #define C_FLAG 0x01
-
-
- // ---- read/write/modify memory --------------------------------------
- #define core(A) CORE[(Short)(A)] // memory access for read-modify-write
- #define peek(A) core(A) // read byte
- #define poke(A,N) core(A)=N // write byte
- #define poke2(A,N) poke(A,N),poke(A+1,N>>8) // write word ((A and N must be constant))
-
- #define n peek(pc++) // get next byte via pc
- #define nn (wm=n,wm+((Short)n<<8)) // get next word via pc
- #define dis (char)n // get signed char via pc
-
- #define pop() (wm=peek(sp++),wm+((Short)peek(sp++)<<8))
- #define push(N) poke(--sp,N>>8), poke(--sp,N)
-
-
- // ---- write to RAM with ROM protection -------------------------------
- // use as last instruction only!
- // Address parameter must be constant
- // Word parameter must be constant
- // Byte parameter may be a calculated expression like (iz+dis)
- // note: rompoke2 may overwrite first byte of ROM and may call write_to_rom() for first byte of RAM
-
- #define in_ram(A) (A>=0x4000)
- #define in_rom(A) (A<0x4000)
- #define rompoke(A,N) if (in_ram(A)) { poke(A,N); loop; } write_to_rom(A,N)
- #define rompoke2(A,N) if (in_ram(A)) { poke2(A,N);loop; } write_to_rom(A,N); write_to_rom(A+1,N>>8)
-
-
-
- // ---- Counting individual instructions and executed locations --------------------
-
- #if PC_PROFILE
- #define COUNT_PC { if (count_pc) if (!++cnt_pc[pc]) Z80_1st_Loc(cc,pc); }
- #else
- #define COUNT_PC
- #endif
-
- #if CMD_PROFILE
- #define COUNT_INSTR { if (count_instr) if (!++cnt_xx[peek(pc)] ) Z80_1st_Instr(cc,pc); }
- #define COUNT_CB_INSTR { if (count_instr) if (!++cnt_cb[peek(pc)] ) Z80_1st_Instr(cc,pc); }
- #define COUNT_ED_INSTR { if (count_instr) if (!++cnt_ed[peek(pc)] ) Z80_1st_Instr(cc,pc); }
- #define COUNT_XY_INSTR { if (count_instr) if (!++cnt_xy[peek(pc)] ) Z80_1st_Instr(cc,pc); }
- #define COUNT_XYCB_INSTR { if (count_instr) if (!++cnt_xycb[peek(pc)]) Z80_1st_Instr(cc,pc); }
- #else
- #define COUNT_INSTR
- #define COUNT_CB_INSTR
- #define COUNT_ED_INSTR
- #define COUNT_XY_INSTR
- #define COUNT_XYCB_INSTR
- #endif
-
-
- // ---- Macros which call Z80_Info(cc,ip) or do nothing ---------------------------------
- // depending on flags defined in z80.options
-
-
- #if INFO_IRPT
- #define do_info_irpt Z80_Info_Irpt ( cc )
- #else
- #define do_info_irpt
- #endif
-
-
- #if INFO_NMI
- #define do_info_nmi Z80_Info_NMI ( cc )
- #else
- #define do_info_nmi
- #endif
-
-
- #if INFO_ILLEGALS
- #define loop_ill2 goto ill2
- #define loop_ill3 goto ill3
- #define loop_ill4 goto ill4
- #else
- #define loop_ill2 loop
- #define loop_ill3 loop
- #define loop_ill4 loop
- #endif
-
-
- #if INFO_WEIRD
- #define loop_weird1 goto weird1
- #define loop_weird2 goto weird2
- #define loop_weird3 goto weird3
- #define loop_weird4 goto weird4
- #else
- #define loop_weird1 loop
- #define loop_weird2 loop
- #define loop_weird3 loop
- #define loop_weird4 loop
- #endif
-
-
- #if INFO_MISC
- #define info_misc1 Z80_Info( cc, pc-1 )
- #define info_misc2 Z80_Info( cc, pc-2 )
- #else
- #define info_misc1
- #define info_misc2
- #endif
-
-
- // ----- Exact register R handling: R is kept in register
- #if EXACT_R
- #define increment_r r++
- #define decrement_r r--
- #define add_r(N) r += N
- #define store_r RR = (RR&0x80) + (r&0x7F)
- #define load_r r = RR
- #define ld_r_a RR = r = ra
- #define ld_a_r ra = (RR&0x80) + (r&0x7F)
-
- // ----- Use register R for random generation only: Bit 7 is kept in RR
- #else
- #define increment_r
- #define decrement_r
- #define add_r(N)
- #define store_r
- #define load_r
- #define ld_r_a RR = ra
- #define ld_a_r ra = (RR&0x80) + (Random()&0x7F)
- #endif
-
-
- // --------------------------------------------------------------------
- // ---- INSTRUCTION MACROS --------------------------------------------
- // --------------------------------------------------------------------
-
- /* RLC ... SRL: set/clr C, Z, P, S;
- clear N=0, H=0
- pres. none
- */
- #define M_RLC(R) \
- rf = R>>7; \
- R = (R<<1)+rf; \
- rf |= zlog_flags[R]
-
- #define M_RRC(R) \
- rf = R&0x01; \
- R = (R>>1)+(rf<<7); \
- rf |= zlog_flags[R]
-
- #define M_RL(R) \
- if (R&0x80) \
- { R = (R<<1)+(rf&0x01); \
- rf = zlog_flags[R]+C_FLAG; \
- } else \
- { R = (R<<1)+(rf&0x01); \
- rf = zlog_flags[R]; \
- }
-
- #define M_RR(R) \
- if (R&0x01) \
- { R = (R>>1)+(rf<<7); \
- rf = zlog_flags[R]+C_FLAG; \
- } else \
- { R = (R>>1)+(rf<<7); \
- rf = zlog_flags[R]; \
- }
-
- #define M_SLA(R) \
- rf = R>>7; \
- R <<= 1; \
- rf |= zlog_flags[R]
-
- #define M_SRA(R) \
- rf = R&0x01; \
- R = (R&0x80)+(R>>1); \
- rf |= zlog_flags[R]
-
- #define M_SLL(R) \
- rf = R>>7; \
- R = (R<<1)+1; \
- rf |= zlog_flags[R]
-
- #define M_SRL(R) \
- rf = R&0x01; \
- R >>= 1; \
- rf |= zlog_flags[R]
-
-
- /* BIT: set/clr Z
- clear N=0, H=1
- pres C
- takes other flags from corresponding bits in tested byte!
- */
- #define M_BIT(N,R) rf = (rf&C_FLAG) + (R&(S_FLAG+P_FLAG)) + H_FLAG + ((R&N)?0:Z_FLAG)
-
-
- /* ADD ... CP: set/clr Z, S, V, C, N, H
- pres none
- */
- #define M_ADD(R) \
- wm = ra+R; \
- rf = wmh + (wml?0:Z_FLAG) + (wml&S_FLAG) \
- + (~(ra^R)&(wml^ra)&0x80?V_FLAG:0) \
- + ((ra^R^wml)&H_FLAG); \
- ra = wml
-
- #define M_SUB(R) \
- wm = ra-R; \
- rf = -wmh + (wml?0:Z_FLAG) + (wml&S_FLAG) \
- + ((ra^R)&(wml^ra)&0x80?V_FLAG:0) \
- + ((ra^R^wml)&H_FLAG) + N_FLAG; \
- ra = wml
-
- #define M_ADC(R) \
- wm = ra+R+(rf&C_FLAG); \
- rf = wmh + (wml?0:Z_FLAG) + (wml&S_FLAG) \
- + (~(ra^R)&(wml^ra)&0x80?V_FLAG:0) \
- + ((ra^R^wml)&H_FLAG); \
- ra = wml
-
- #define M_SBC(R) \
- wm = ra-R-(rf&C_FLAG); \
- rf = -wmh + (wml?0:Z_FLAG) + (wml&S_FLAG) \
- + ((ra^R)&(wml^ra)&0x80?V_FLAG:0) \
- + ((ra^R^wml)&H_FLAG) + N_FLAG; \
- ra = wml
-
- #define M_CP(R) \
- wm = ra-R; \
- rf = -wmh + (wml?0:Z_FLAG) + (wml&S_FLAG) \
- + ((ra^R)&(wml^ra)&0x80?V_FLAG:0) \
- + ((ra^R^wml)&H_FLAG) + N_FLAG;
-
-
- /* AND ... XOR: set/clr Z, P, S
- clear C=0, N=0, H=0/1 (OR,XOR/AND)
- pres none
- */
- #define M_AND(R) \
- ra &= R; \
- rf = H_FLAG|zlog_flags[ra]
-
- #define M_OR(R) \
- ra |= R; \
- rf = zlog_flags[ra]
-
- #define M_XOR(R) \
- ra ^= R; \
- rf = zlog_flags[ra]
-
-
- /* INC ... DEC: set/clr Z,P,S,H
- clear N=0/1 (INC/DEC)
- pres C
- */
- #define M_INC(R) \
- R++; \
- rf = (rf&C_FLAG) + (R?0:Z_FLAG) + (R&S_FLAG) + (R==0x80?V_FLAG:0) + (R&0x0F?0:H_FLAG)
-
- #define M_DEC(R) \
- R--; \
- rf = (rf&C_FLAG) + (R?0:Z_FLAG) + (R&S_FLAG) + (R==0x7F?V_FLAG:0) + (((R+1)&0x0F)?0:H_FLAG) + N_FLAG
-
-
- /* ADDW: set/clr C
- clear N=0
- pres Z, P, S
- unkn H
- */
- #define M_ADDW(R1,R2) \
- rf &= ~(N_FLAG+C_FLAG); \
- rf |= ((Long)R1+(Long)R2)>>16; \
- R1 += R2;
-
-
- /* ADCW, SBCW: set/clr C,Z,V,S
- clear N=0/1 (ADC/SBC)
- unkn H
- pres none
- */
- #define M_ADCW(R) \
- wm = HL+R+(rf&C_FLAG); \
- rf = (((Long)HL+(Long)R+(rf&C_FLAG))>>16) \
- + (wm?0:Z_FLAG) + (wmh&S_FLAG) \
- + (~(HL^R)&(wm^HL)&0x8000?V_FLAG:0);\
- HL = wm
-
- #define M_SBCW(R) \
- wm = HL-R-(rf&C_FLAG); \
- rf = (((Long)HL-(Long)R-(rf&C_FLAG))>>31) \
- + (wm?0:Z_FLAG) + (wmh&S_FLAG) \
- + ((HL^R)&(wm^HL)&0x8000?V_FLAG:0) \
- + N_FLAG; \
- HL = wm
-
- /* IN set/clr Z, P, S, H
- clear N=0
- pres C
- */
- #define M_IN(R) \
- R = Do_Input(BC); \
- rf = (rf&C_FLAG) + zlog_flags[R]
-
-
-
-
-
-
-
-
-
-
-